﻿using Microsoft.Win32;
using System;
using System.Security;

namespace YougeBookmark.Utils
{
    /// <summary>
    /// 注册表操作帮助类（支持32/64位系统）
    /// </summary>
    public /*static*/ class RegistryHelper
    {
        /// <summary>
        /// 设置开机自启动
        /// </summary>
        /// <param name="appName">应用名称</param>
        /// <param name="executablePath">可执行文件完整路径</param>
        /// <param name="allUsers">是否为所有用户设置</param>
        public static void SetAutoStart(string appName, string executablePath, bool allUsers = false)
        {
            try
            {
                var baseKey = allUsers ? Registry.LocalMachine : Registry.CurrentUser;
                using var runKey = GetRegistryKey(
                    baseKey,
                    @"Software\Microsoft\Windows\CurrentVersion\Run",
                    writable: true
                );

                runKey?.SetValue(appName, $"\"{executablePath}\"");
            }
            catch (SecurityException ex)
            {
                throw new UnauthorizedAccessException("需要管理员权限修改系统注册表", ex);
            }
        }

        /// <summary>
        /// 读取注册表值
        /// </summary>
        public static T ReadValue<T>(RegistryHive hive,
                                    string subKeyPath,
                                    string valueName,
                                    T defaultValue = default,
                                    RegistryView view = RegistryView.Default)
        {
            using var baseKey = RegistryKey.OpenBaseKey(hive, view);
            using var subKey = baseKey.OpenSubKey(subKeyPath);

            return subKey != null
                ? (T)Convert.ChangeType(subKey.GetValue(valueName, defaultValue), typeof(T))
                : defaultValue;
        }

        /// <summary>
        /// 写入注册表值
        /// </summary>
        public static bool WriteValue(RegistryHive hive,
                                    string subKeyPath,
                                    string valueName,
                                    object value,
                                    RegistryValueKind valueKind = RegistryValueKind.String,
                                    RegistryView view = RegistryView.Default)
        {
            try
            {
                using var baseKey = RegistryKey.OpenBaseKey(hive, view);
                using var subKey = baseKey.CreateSubKey(subKeyPath, true);

                subKey.SetValue(valueName, value, valueKind);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 删除注册表项
        /// </summary>
        public static bool DeleteKey(RegistryHive hive,
                                    string subKeyPath,
                                    RegistryView view = RegistryView.Default)
        {
            try
            {
                using var baseKey = RegistryKey.OpenBaseKey(hive, view);
                baseKey.DeleteSubKeyTree(subKeyPath);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 检查注册表项是否存在
        /// </summary>
        public static bool KeyExists(RegistryHive hive,
                                    string subKeyPath,
                                    RegistryView view = RegistryView.Default)
        {
            using var baseKey = RegistryKey.OpenBaseKey(hive, view);
            using var subKey = baseKey.OpenSubKey(subKeyPath);
            return subKey != null;
        }

        /// <summary>
        /// 获取注册表键（带异常处理）
        /// </summary>
        private static RegistryKey GetRegistryKey(
            RegistryKey baseKey,
            string subKeyPath,
            bool writable = false,
            RegistryView view = RegistryView.Default)
        {
            try
            {
                var finalKey = baseKey ?? RegistryKey.OpenBaseKey(baseKey.Name switch
                {
                    "HKEY_CURRENT_USER" => RegistryHive.CurrentUser,
                    "HKEY_LOCAL_MACHINE" => RegistryHive.LocalMachine,
                    _ => RegistryHive.CurrentUser
                }, view);

                return finalKey.OpenSubKey(subKeyPath, writable)
                    ?? finalKey.CreateSubKey(subKeyPath, writable);
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 获取安装路径（支持查找MSI安装程序）
        /// </summary>
        public static string GetInstallPath(string appGuid)
        {
            const string uninstallKey = @"Software\Microsoft\Windows\CurrentVersion\Uninstall";
            return ReadValue(RegistryHive.LocalMachine,
                $@"{uninstallKey}\{appGuid}",
                "InstallLocation",
                string.Empty);
        }
    }
}